﻿using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using ZhiJiao.Dal;
using ZhiJiao.Models.Entities;
using ZhiJiao.Models.Entities.Enums;
using ZhiJiao.Service.Abstracts;
using ZhiJiao.Service.Dto;

namespace ZhiJiao.Service.Services
{
    /// <summary>
    /// 角色管理相关服务
    /// </summary>
    public class RoleService:IRoleService
    {
        private readonly RoleManager<Role> _roleManager;
        private readonly BackJson res;
        private readonly ZJDbContext _db;
        public RoleService(RoleManager<Role> roleManager,
                           BackJson backJson,
                           ZJDbContext zJDbContext)
        {
            _roleManager = roleManager;
            res = backJson;
            _db = zJDbContext;
        }


        /// <summary>
        /// 获取角色列表
        /// </summary>
        public BackJson GetRoleList(RoleType roleType, string roleName,long? insId)
        {
            try
            {
                List<Role> list = null;
                var query = _db.Roles.Include(r=>r.Instruction).Include(r=>r.Modules).AsQueryable();
                if (!string.IsNullOrEmpty(roleName))
                {
                    query = query.Where(r => r.Name.Contains(roleName));
                }
                if (roleType == RoleType.Plat)
                {
                    query = query.Where(r => r.Type == RoleType.Plat);
                }
                else
                {
                    query = query.Where(r => r.Type == RoleType.Instruction);
                    if (insId != null)
                    {
                        query = query.Where(r =>r.Instruction!=null && r.Instruction.Id == insId);
                    }
                }
                list = query.ToList();
                res.code = 0;
                res.data = list.Select(r => new
                {
                    name = r.Name,
                    id = r.Id,
                    desc = r.Describe,
                    type=(int)r.Type,
                    insId=r.Instruction!=null?r.Instruction.Id:-1,
                    modules=r.Modules?.Select(m=>new { id=m.Id,name=m.Name}).ToArray()
                });
            }
            catch (Exception e)
            {
                res.code = 1;
                res.msg = e.Message;
            }
            return res;
        }

        /// <summary>
        /// 添加角色
        /// </summary>
        public async Task<BackJson> AddSubmit(AddRloeDto model)
        {
            Role role = null;
            List<Module> modules = new List<Module>();
            if (!string.IsNullOrEmpty(model.Modules))
            {
                var mList = model.Modules.Split(',');
                foreach (string id in mList)
                {
                    long moduleId = Convert.ToInt64(id);
                    var module = _db.Modules.FirstOrDefault(m => m.Id == moduleId);
                    if (module != null)
                    {
                        modules.Add(module);
                    }
                }
            }
            // 机构角色
            if (model.Type == RoleType.Instruction)
            {
                var ins = _db.Instructions.FirstOrDefault(i => i.Id == model.InsId);
                 role = new Role
                {
                    Name = model.Name,
                    NormalizedName=model.Name,
                    Modules = modules,
                    Describe = model.desc,
                    Instruction = ins,
                    Type = model.Type
                };
            }
            else 
            {
                role = new Role
                {
                    Name = model.Name,
                    NormalizedName= model.Name,
                    Modules = modules,
                    Describe = model.desc,
                    Instruction = null,
                    Type = model.Type
                };
            }
            
            var result = await _roleManager.CreateAsync(role);
            if (result.Succeeded)
            {
                res.code = 0;
                res.msg = "角色添加成功！";
                return res;
            }
            res.code = 1;
            foreach (var err in result.Errors)
            {
                res.msg += (err.Description+"\r\n");
            }
            return res;
        }

        /// <summary>
        /// 提交角色修改
        /// </summary>
        public async Task<BackJson> SubmitEdit(AddRloeDto model)
        {
            using (_db)
            {
                try
                {
                    List<Module> modules = new List<Module>();
                    if (!string.IsNullOrEmpty(model.Modules))
                    {
                        var mList = model.Modules.Split(',');
                        foreach (string id in mList)
                        {
                            long moduleId = Convert.ToInt64(id);
                            var module = _db.Modules.FirstOrDefault(m => m.Id == moduleId);
                            if (module != null)
                            {
                                modules.Add(module);
                            }
                        }
                    }
                    var role = _db.Roles.Include(r => r.Modules).FirstOrDefault(r => r.Id == model.Id);
                    role!.Name = model.Name;
                    role.NormalizedName = model.Name;
                    role.Modules?.RemoveAll(m => true);
                    foreach (var mod in modules)
                    {
                        role.Modules?.Add(mod);
                    }
                    role.Describe = model.desc;
                    _db.Roles.Update(role);
                    int result = _db.SaveChanges();
                    if (result > 0)
                    {
                        res.code = 0;
                        res.msg = "角色保存成功！";
                    }
                }
                catch (Exception e)
                {
                    res.code = 1;
                    res.msg = e.Message;
                }
                return res;
            }
        }


        /// <summary>
        /// 删除角色
        /// </summary>
        public async Task<BackJson> Delete(string Id)
        {
            try
            {
                var role = await _roleManager.FindByIdAsync(Id);
                var result = await _roleManager.DeleteAsync(role);
                if (result.Succeeded)
                {
                    res.code = 0;
                    res.msg = "角色删除成功。";
                }
                else {
                    res.code = 1;
                    foreach (var err in result.Errors)
                    {
                        res.msg += (err.Description + "\r\n");
                    }
                }
            }
            catch (Exception e)
            {
                res.code = 1;
                res.msg = e.Message;
            }

            return res;
        }

        /// <summary>
        /// 获取角色对象
        /// </summary>
        public async Task<BackJson> GetRole(string Id)
        {
            var role = await _roleManager.FindByIdAsync(Id);
            res.code = 0;
            res.data = role;
            return res;
        }


        public async Task<BackJson> GetModules(RoleType type)
        {
            var query = _db.Modules.AsQueryable();

            if (type == RoleType.Plat)
            {
                query = query.Where(m => m.Type == ModuleType.Plat || m.Type == ModuleType.Common);
            }
            else 
            {
                query = query.Where(m=>m.Type==ModuleType.Instruction || m.Type==ModuleType.Common);
            }

            query = query.Where(m=>m.Flag==true && m.ParentModule==null);

            var list = await query.ToListAsync();
            for (int i = 0; i < list.Count; i++)
            {
                list[i].Children = _db.Modules.Where(m => m.ParentModule == list[i]).ToList();
            };
            var mList=list.Select(m => new
                        {
                            id = m.Id,
                            label = m.Name,
                            icon = m.Icon,
                            children = m.Children?.Select(c => new {
                                id=c.Id,
                                label=c.Name,
                                icon=c.Icon
                            })
                        });

            res.code = 0;
            res.data = mList;
            return res;
        }
    }
}
